﻿using Microsoft.AspNetCore.Mvc;
using SD.Infrastructure.DTOBase;
using SD.Toolkits.AspNetCore.Attributes;
using SlamDunk.MES.IAppService.DTOs.Inputs;
using SlamDunk.MES.IAppService.DTOs.Outputs.StockContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.ValueObjects.Enums;
using System;
using System.Collections.Generic;

namespace SlamDunk.MES.AppService.Host.Controllers
{
    /// <summary>
    /// 库存单据服务WebApi接口
    /// </summary>
    [ApiController]
    [Route("Api/[controller]/[action]")]
    public class StockOrderController : ControllerBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 库存单据服务契约接口
        /// </summary>
        private readonly IStockOrderContract _stockOrderContract;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public StockOrderController(IStockOrderContract stockOrderContract)
        {
            this._stockOrderContract = stockOrderContract;
        }

        #endregion


        //命令部分

        #region # 创建库存单据类 —— void CreateStockOrderClass(string classNo, string className...
        /// <summary>
        /// 创建库存单据类
        /// </summary>
        /// <param name="classNo">库存单据类编号</param>
        /// <param name="className">库存单据类名称</param>
        /// <param name="directionType">出入库方向类型</param>
        /// <param name="generateBarcode">是否生成条码</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        [HttpPost]
        [WrapPostParameters]
        public void CreateStockOrderClass(string classNo, string className, StockDirectionType directionType, bool? generateBarcode, Guid? facilityId, string description)
        {
            this._stockOrderContract.CreateStockOrderClass(classNo, className, directionType, generateBarcode, facilityId, description);
        }
        #endregion

        #region # 修改库存单据类 —— void UpdateStockOrderClass(Guid stockOrderClassId, string classNo...
        /// <summary>
        /// 修改库存单据类
        /// </summary>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        /// <param name="classNo">库存单据类编号</param>
        /// <param name="className">库存单据类名称</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        [HttpPost]
        [WrapPostParameters]
        public void UpdateStockOrderClass(Guid stockOrderClassId, string classNo, string className, Guid? facilityId, string description)
        {
            this._stockOrderContract.UpdateStockOrderClass(stockOrderClassId, classNo, className, facilityId, description);
        }
        #endregion

        #region # 删除库存单据类 —— void RemoveStockOrderClass(Guid stockOrderClassId)
        /// <summary>
        /// 删除库存单据类
        /// </summary>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        [HttpPost]
        [WrapPostParameters]
        public void RemoveStockOrderClass(Guid stockOrderClassId)
        {
            this._stockOrderContract.RemoveStockOrderClass(stockOrderClassId);
        }
        #endregion

        #region # 创建入库单 —— void CreateStockInOrder(string orderNo, Guid stockOrderClassId...
        /// <summary>
        /// 创建入库单
        /// </summary>
        /// <param name="orderNo">单据编号</param>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        /// <param name="sourceOrderType">源单据类型</param>
        /// <param name="sourceOrderId">源单据Id</param>
        /// <param name="sourceOrderName">源单据名称</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="targetStorageLocationName">目标储存位置名称</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        /// <param name="detailParams">入库单明细参数模型集</param>
        [HttpPost]
        [WrapPostParameters]
        public void CreateStockInOrder(string orderNo, Guid stockOrderClassId, SourceOrderType? sourceOrderType, string sourceOrderId, string sourceOrderName, StorageLocationType targetStorageLocationType, string targetStorageLocationId, string targetStorageLocationName, Guid? facilityId, string description, IEnumerable<StockInOrderDetailParam> detailParams)
        {
            this._stockOrderContract.CreateStockInOrder(orderNo, stockOrderClassId, sourceOrderType, sourceOrderId, sourceOrderName, targetStorageLocationType, targetStorageLocationId, targetStorageLocationName, facilityId, description, detailParams);
        }
        #endregion

        #region # 修改入库单 —— void UpdateStockInOrder(Guid stockInOrderId, StorageLocationType...
        /// <summary>
        /// 修改入库单
        /// </summary>
        /// <param name="stockInOrderId">入库单Id</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="targetStorageLocationName">目标储存位置名称</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        /// <param name="detailParams">入库单明细参数模型集</param>
        [HttpPost]
        [WrapPostParameters]
        public void UpdateStockInOrder(Guid stockInOrderId, StorageLocationType targetStorageLocationType, string targetStorageLocationId, string targetStorageLocationName, Guid? facilityId, string description, IEnumerable<StockInOrderDetailParam> detailParams)
        {
            this._stockOrderContract.UpdateStockInOrder(stockInOrderId, targetStorageLocationType, targetStorageLocationId, targetStorageLocationName, facilityId, description, detailParams);
        }
        #endregion

        #region # 创建出库单 —— void CreateStockOutOrder(string orderNo, Guid stockOrderClassId...
        /// <summary>
        /// 创建出库单
        /// </summary>
        /// <param name="orderNo">单据编号</param>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        /// <param name="sourceOrderType">源单据类型</param>
        /// <param name="sourceOrderId">源单据Id</param>
        /// <param name="sourceOrderName">源单据名称</param>
        /// <param name="sourceStorageLocationType">源储存位置类型</param>
        /// <param name="sourceStorageLocationId">源储存位置Id</param>
        /// <param name="sourceStorageLocationName">源储存位置名称</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="targetStorageLocationName">目标储存位置名称</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        /// <param name="detailParams">出库单明细参数模型集</param>
        [HttpPost]
        [WrapPostParameters]
        public void CreateStockOutOrder(string orderNo, Guid stockOrderClassId, SourceOrderType? sourceOrderType, string sourceOrderId, string sourceOrderName, StorageLocationType sourceStorageLocationType, string sourceStorageLocationId, string sourceStorageLocationName, StorageLocationType targetStorageLocationType, string targetStorageLocationId, string targetStorageLocationName, Guid? facilityId, string description, IEnumerable<StockOutOrderDetailParam> detailParams)
        {
            this._stockOrderContract.CreateStockOutOrder(orderNo, stockOrderClassId, sourceOrderType, sourceOrderId, sourceOrderName, sourceStorageLocationType, sourceStorageLocationId, sourceStorageLocationName, targetStorageLocationType, targetStorageLocationId, targetStorageLocationName, facilityId, description, detailParams);
        }
        #endregion

        #region # 修改出库单 —— void UpdateStockOutOrder(Guid stockOutOrderId, StorageLocationType...
        /// <summary>
        /// 修改出库单
        /// </summary>
        /// <param name="stockOutOrderId">出库单Id</param>
        /// <param name="sourceStorageLocationType">源储存位置类型</param>
        /// <param name="sourceStorageLocationId">源储存位置Id</param>
        /// <param name="sourceStorageLocationName">源储存位置名称</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="targetStorageLocationName">目标储存位置名称</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="description">描述</param>
        /// <param name="detailParams"></param>
        [HttpPost]
        [WrapPostParameters]
        public void UpdateStockOutOrder(Guid stockOutOrderId, StorageLocationType sourceStorageLocationType, string sourceStorageLocationId, string sourceStorageLocationName, StorageLocationType targetStorageLocationType, string targetStorageLocationId, string targetStorageLocationName, Guid? facilityId, string description, IEnumerable<StockOutOrderDetailParam> detailParams)
        {
            this._stockOrderContract.UpdateStockOutOrder(stockOutOrderId, sourceStorageLocationType, sourceStorageLocationId, sourceStorageLocationName, targetStorageLocationType, targetStorageLocationId, targetStorageLocationName, facilityId, description, detailParams);
        }
        #endregion

        #region # 提交审核库存单据 —— void SubmitStockOrder(Guid stockOrderId)
        /// <summary>
        /// 提交审核库存单据
        /// </summary>
        /// <param name="stockOrderId">库存单据Id</param>
        [HttpPost]
        [WrapPostParameters]
        public void SubmitStockOrder(Guid stockOrderId)
        {
            this._stockOrderContract.SubmitStockOrder(stockOrderId);
        }
        #endregion

        #region # 批量提交审核库存单据 —— void SubmitStockOrders(IEnumerable<Guid>...
        /// <summary>
        /// 批量提交审核库存单据
        /// </summary>
        /// <param name="stockOrderIds">库存单据Id集</param>
        [HttpPost]
        [WrapPostParameters]
        public void SubmitStockOrders(IEnumerable<Guid> stockOrderIds)
        {
            this._stockOrderContract.SubmitStockOrders(stockOrderIds);
        }
        #endregion

        #region # 审核库存单据 —— void CheckStockOrder(Guid stockOrderId...
        /// <summary>
        /// 审核库存单据
        /// </summary>
        /// <param name="stockOrderId">库存单据Id</param>
        /// <param name="passed">是否通过</param>
        /// <param name="checkedRemark">审核意见</param>
        [HttpPost]
        [WrapPostParameters]
        public void CheckStockOrder(Guid stockOrderId, bool passed, string checkedRemark)
        {
            this._stockOrderContract.CheckStockOrder(stockOrderId, passed, checkedRemark);
        }
        #endregion

        #region # 打印库存单据条码 —— void PrintStockOrderBarcode(Guid stockOrderId, Guid stockOrderDetailId)
        /// <summary>
        /// 打印库存单据条码
        /// </summary>
        /// <param name="stockOrderId">库存单据Id</param>
        /// <param name="stockOrderDetailId">库存单据明细Id</param>
        [HttpPost]
        [WrapPostParameters]
        public void PrintStockOrderBarcode(Guid stockOrderId, Guid stockOrderDetailId)
        {
            this._stockOrderContract.PrintStockOrderBarcode(stockOrderId, stockOrderDetailId);
        }
        #endregion


        //查询部分

        #region # 分页获取库存单据类列表 —— PageModel<StockOrderClassInfo> GetStockOrderClassesByPage(...
        /// <summary>
        /// 分页获取库存单据类列表
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <param name="directionType">出/入库方向类型</param>
        /// <param name="generateBarcode">是否生成条码</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <returns>库存单据类列表</returns>
        [HttpGet]
        public PageModel<StockOrderClassInfo> GetStockOrderClassesByPage(string keywords, StockDirectionType? directionType, bool? generateBarcode, Guid? facilityId, int pageIndex, int pageSize)
        {
            return this._stockOrderContract.GetStockOrderClassesByPage(keywords, directionType, generateBarcode, facilityId, pageIndex, pageSize);
        }
        #endregion

        #region # 分页获取入库单列表 —— PageModel<StockInOrderInfo> GetStockInOrdersByPage(string keywords...
        /// <summary>
        /// 分页获取入库单列表
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        /// <param name="checkStatus">审核状态</param>
        /// <param name="sourceOrderType">源单据类型</param>
        /// <param name="sourceOrderId">源单据Id</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="generateBarcode">是否生成条码</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <returns>入库单列表</returns>
        [HttpGet]
        public PageModel<StockInOrderInfo> GetStockInOrdersByPage(string keywords, Guid? stockOrderClassId, CheckStatus? checkStatus, SourceOrderType? sourceOrderType, string sourceOrderId, StorageLocationType? targetStorageLocationType, string targetStorageLocationId, bool? generateBarcode, DateTime? startTime, DateTime? endTime, Guid? facilityId, int pageIndex, int pageSize)
        {
            return this._stockOrderContract.GetStockInOrdersByPage(keywords, stockOrderClassId, checkStatus, sourceOrderType, sourceOrderId, targetStorageLocationType, targetStorageLocationId, generateBarcode, startTime, endTime, facilityId, pageIndex, pageSize);
        }
        #endregion

        #region # 分页获取出库单列表 —— PageModel<StockOutOrderInfo> GetStockOutOrdersByPage(string keywords...
        /// <summary>
        /// 分页获取出库单列表
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <param name="stockOrderClassId">库存单据类Id</param>
        /// <param name="checkStatus">审核状态</param>
        /// <param name="sourceOrderType">源单据类型</param>
        /// <param name="sourceOrderId">源单据Id</param>
        /// <param name="sourceStorageLocationType">源储存位置类型</param>
        /// <param name="sourceStorageLocationId">目标储存位置Id</param>
        /// <param name="targetStorageLocationType">目标储存位置类型</param>
        /// <param name="targetStorageLocationId">目标储存位置Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="facilityId">工厂模型Id</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <returns>出库单列表</returns>
        [HttpGet]
        public PageModel<StockOutOrderInfo> GetStockOutOrdersByPage(string keywords, Guid? stockOrderClassId, CheckStatus? checkStatus, SourceOrderType? sourceOrderType, string sourceOrderId, StorageLocationType? sourceStorageLocationType, string sourceStorageLocationId, StorageLocationType? targetStorageLocationType, string targetStorageLocationId, DateTime? startTime, DateTime? endTime, Guid? facilityId, int pageIndex, int pageSize)
        {
            return this._stockOrderContract.GetStockOutOrdersByPage(keywords, stockOrderClassId, checkStatus, sourceOrderType, sourceOrderId, sourceStorageLocationType, sourceStorageLocationId, targetStorageLocationType, targetStorageLocationId, startTime, endTime, facilityId, pageIndex, pageSize);
        }
        #endregion

        #region # 获取库存单据明细列表 —— IEnumerable<StockOrderDetailInfo> GetStockOrderDetails(Guid stockOrderId)
        /// <summary>
        /// 获取库存单据明细列表
        /// </summary>
        /// <param name="stockOrderId">库存单据Id</param>
        /// <returns>库存单据明细列表</returns>
        [HttpGet]
        public IEnumerable<StockOrderDetailInfo> GetStockOrderDetails(Guid stockOrderId)
        {
            return this._stockOrderContract.GetStockOrderDetails(stockOrderId);
        }
        #endregion
    }
}
